﻿using System.Collections.Generic;
using System.Linq;
using CodeStash.Common.DataAccess.EntityFramework;
using CodeStash.Common.DataAccess.Repository;
using CodeStash.Common.DataAccess.UnitOfWork;
using CodeStash.Models.TagCloud;
using CodeStash.Common.Enums;
using System;
using System.Web.Security;
using CodeStash.Utils;

namespace CodeStash.Services
{
    public class TagCloudService : ITagCloudService
    {
        private readonly IUnitOfWork unitOfWork;
        private readonly IRepository<CodeSnippet> codeSnippetRepository;
        private readonly IRepository<CodeCategory> codeCategoryRepository;
        private readonly IRepository<CreatedTeam> createdTeamRepository;

        //[ImportingConstructor]
        public TagCloudService(IUnitOfWork unitOfWork,
                              IRepository<CreatedTeam> createdTeamRepository,
                              IRepository<CodeSnippet> codeSnippetRepository,
                              IRepository<CodeCategory> codeCategoryRepository)
        {
            this.unitOfWork = unitOfWork;
            this.codeSnippetRepository = codeSnippetRepository;
            this.codeCategoryRepository = codeCategoryRepository;
            this.createdTeamRepository = createdTeamRepository;
        }


        public IEnumerable<TagCategoryModel> CreateTagCloud()
        {

            using (unitOfWork)
            {
                codeSnippetRepository.EnrolInUnitOfWork(unitOfWork);
                codeCategoryRepository.EnrolInUnitOfWork(unitOfWork);

                int totalCodeSnippets = codeSnippetRepository.FindAll().Count();

                var user = Membership.GetUser();
                Guid userId = Guid.Empty;
                if (user != null)
                {
                    userId = Guid.Parse(user.ProviderUserKey.ToString());
                }
                List<Guid> teamUserIds = SearchUtils.GetListOfUserIdsInSameTeamAsCurrentUser(unitOfWork, createdTeamRepository, userId);

                var categories = codeCategoryRepository.FindAll("CodeSnippets").AsEnumerable();

                Func<CodeSnippet, bool> predicate2 = x => x.Visibility == (int)CodeSnippetVisibility.Public ||
                    (user != null && x.AspNetMembershipUserId == userId && x.Visibility == (int)CodeSnippetVisibility.JustMe) ||
                    (user != null && teamUserIds.Contains(x.AspNetMembershipUserId) && x.Visibility == (int)CodeSnippetVisibility.MyTeam);

                var tagCategories =
                    (from c in categories
                     where c.CodeSnippets.Any(predicate2)
                     orderby c.CodeCategoryName
                     select new TagCategoryModel
                     {
                         CategoryId = c.CodeCategoryId,
                         CategoryName = string.Format("{0}", c.CodeCategoryName.Trim()),
                         CountOfCategory = c.CodeSnippets.Count(),
                         TotalArticles = totalCodeSnippets
                     });

                return (from x in tagCategories
                        where x.CountOfCategory > 0
                        orderby x.CountOfCategory descending
                        select x).ToList();
            }
        }
    }
}